#include "VSPointLight.h"
#include "VSGraphicInclude.h"
#include "VSSceneRender.h"
#include "VSStream.h"
using namespace VSEngine2;
IMPLEMENT_RTTI(VSPointLight,VSLight)
static bool gs_bStreamRegistered_VSPointLight = VSPointLight::RegisterMainFactory();
bool VSPointLight::ms_bRegisterMainFactory = false;
bool VSPointLight::RegisterMainFactory()
{
	if (!ms_bRegisterMainFactory)
	{ 
		VSMain::AddInitialFuntion(VSPointLight::InitialClassFactory); 
		ms_bRegisterMainFactory = true;
	} 
	return ms_bRegisterMainFactory;

}
bool VSPointLight::InitialClassFactory()
{
	ms_ClassFactory.AddElement(ms_Type.GetName(),FactoryFunc);
	
	return 1;
}
VSObject * VSPointLight::FactoryFunc()
{
	return VS_NEW VSPointLight;

}
VSPointLight::VSPointLight()
{
	m_Attenuation0	= 1.0;
	m_Attenuation1	= 0.0;
	m_Attenuation2	= 0.0;
	for (unsigned int i = 0 ; i < 6 ;i++)
	{
		m_pCamera[i] = NULL;
		m_pShadowMapSceneRender[i] = NULL;
	}
	for (unsigned int i = 0 ; i < 6 ;i++)
	{

		m_pCamera[i] = VS_NEW VSCamera();
		m_pCamera[i]->SetLocalTransform(m_Local);
		m_pShadowMapSceneRender[i] = VS_NEW VSShadowMapSceneRender();

	}
	SetShadowMapPara(512,1.0f,512.0f);
}
VSPointLight::~VSPointLight()
{
	for (unsigned int i = 0 ; i < 6 ;i++)
	{
		m_pCamera[i] = NULL;
		VSMAC_DELETE(m_pShadowMapSceneRender[i]);
	}
}
unsigned int VSPointLight::DiskUse()const
{
	unsigned int Use = VSLight::DiskUse();
	Use += sizeof(VSREAL) * 3;
	return Use;
}
bool VSPointLight::Save(VSStream & rStream,unsigned int &iSaveUse)const
{
	if(!VSLight::Save(rStream,iSaveUse))
		return 0;



	if(!rStream.Write(&m_Attenuation0,sizeof(VSREAL)))
		return 0;
	iSaveUse += sizeof(VSREAL);

	if(!rStream.Write(&m_Attenuation1,sizeof(VSREAL)))
		return 0;
	iSaveUse += sizeof(VSREAL);

	if(!rStream.Write(&m_Attenuation2,sizeof(VSREAL)))
		return 0;
	iSaveUse += sizeof(VSREAL);
	return 1;
}
bool VSPointLight::Load(VSStream & rStream,unsigned int &iSaveUse)
{
	if(!VSLight::Load(rStream,iSaveUse))
		return 0;


	if(!rStream.Read(&m_Attenuation0,sizeof(VSREAL)))
		return 0;
	iSaveUse += sizeof(VSREAL);

	if(!rStream.Read(&m_Attenuation1,sizeof(VSREAL)))
		return 0;
	iSaveUse += sizeof(VSREAL);

	if(!rStream.Read(&m_Attenuation2,sizeof(VSREAL)))
		return 0;
	iSaveUse += sizeof(VSREAL);

	for (unsigned int i = 0 ; i < 6 ;i++)
	{

		m_pCamera[i]->SetLocalTransform(m_Local);
	}
	SetShadowMapPara(m_uiRTWidth,m_fZN,m_fZF);
	return 1;
}
bool VSPointLight::Clone(const VSObject *pObject,unsigned int uiType)
{
	const VSPointLight* Temp = DynamicCast<VSPointLight>(pObject); 
	if(!Temp)
		return 0;
	if(VSLight::Clone(pObject,uiType))
	{

		m_Attenuation0 = Temp->m_Attenuation0;
		m_Attenuation1 = Temp->m_Attenuation1;
		m_Attenuation2 = Temp->m_Attenuation2;

		for (unsigned int i = 0 ; i < 6 ;i++)
		{

			m_pCamera[i]->SetLocalTransform(m_Local);
		}
		SetShadowMapPara(m_uiRTWidth,m_fZN,m_fZF);

		return 1;
	}
	else
	{
		return 0;

	}

}
void VSPointLight::DrawShadowMap(VSArray<VSScene *> & pSceneArray,double dAppTime)
{
	if (!m_bIsCastShadow)
	{
		return ;
	}
// 	for (unsigned int i = 0 ; i < 6 ; i++)
// 	{
// 		if (m_pShadowMapSceneRender[i] && m_pCamera[i])
// 		{
// 			m_pShadowMapSceneRender[i]->Draw(pSceneArray,m_pCamera[i],dAppTime);
// 		}
// 		else
// 		{
// 			VSMAC_ASSERT(0);
// 		}
// 	}
	
}
void VSPointLight::SetShadowMapPara(unsigned int uiWidth,VSREAL fZN,VSREAL fZF)
{
	m_uiRTWidth = uiWidth;
	m_uiRTHeight = uiWidth;
	m_fZF = fZF;
	m_fZN = fZN;
	for (unsigned int i = 0 ; i < 6 ; i++)
	{
		if (m_pShadowMapSceneRender[i] && m_pCamera[i])
		{
// 			if(m_pShadowMapSceneRender[i]->IsReCreate(uiWidth,uiWidth))
// 			{
// 				m_pShadowMapSceneRender[i]->CreateRT(uiWidth,uiWidth);	
// 			}
			m_pCamera[i]->SetPerspectiveFov(AngleToRadian(90.0f),1.0f,fZN,fZF);
		}
		else
		{
			VSMAC_ASSERT(0);
		}
	}
}
void VSPointLight::UpdateAll(double dAppTime) 
{ 

	VSLight::UpdateAll(dAppTime);
	for (unsigned int i = 0 ; i < 6 ; i++)
	{
		if (m_pCamera[i])
		{
			m_pCamera[i]->UpdateAll(dAppTime);
		}
	}

} 